package com.gitee.cirnochat.file.service;

import com.gitee.cirnochat.common.config.CosClientConfig;
import com.gitee.cirnochat.common.exception.BusinessException;
import com.gitee.cirnochat.common.exception.FileUploadException;
import com.gitee.cirnochat.common.model.enums.ErrorCode;
import com.gitee.cirnochat.file.model.entity.FileStorageRecord;
import com.gitee.cirnochat.file.model.vo.resp.FileUploadResponse;
import com.gitee.cirnochat.user.model.entity.User;
import com.gitee.cirnochat.user.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import static com.gitee.cirnochat.common.constant.FileConstant.UPLOAD_USER_AVATAR_DIR;


@Service
@Slf4j
@RequiredArgsConstructor
public class FileManager implements InitializingBean {
    private final UserService userService;
    private final CosClientConfig cosClientConfig;
    private final FileStorageRecordService fileService;
    private final StorageService storageService;

    private static String COS_HOST;

    @Override
    public void afterPropertiesSet() throws Exception {
        COS_HOST = cosClientConfig.getCosHost();
    }

    private static final String AVATAR_EXTENSION = "png";

    /**
     * 上传用户头像
     *
     * @param file   文件
     * @param userId 请求
     * @return 用户头像信息
     */
    public FileUploadResponse uploadUserAvatar(MultipartFile file, Long userId) {
        String fileUploadPath = String.format(UPLOAD_USER_AVATAR_DIR + "/%s.%s", userId, AVATAR_EXTENSION);
        final User currentUser = userService.getById(userId);
        final FileUploadResponse vo = new FileUploadResponse();
        fileService.uploadFile(file, fileUploadPath, COS_HOST, false,
                (res) -> {
                   BeanUtils.copyProperties(res, vo);
                },
                (e) -> {
                    handleFileUploadExceptionAsync(e);
                    log.error("上传头像失败", e);
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传头像失败");
                });
        if (currentUser.getAvatar() == null) {
            currentUser.setAvatar(vo.getFileUrl());
            userService.updateUserAvatar(userId, fileUploadPath);
        }
        return vo;
    }


    /**
     * 处理文件上传异常
     * @param e
     */
    @Async
    protected void handleFileUploadExceptionAsync(Exception e) {
        if (e instanceof FileUploadException fue) {
            String fileUrl = fue.getFileUrl();
            if (fileUrl != null) {
                storageService.deleteFile(fileUrl);
            }
        }
    }

    public FileUploadResponse uploadFile(MultipartFile file) {
        final FileUploadResponse vo = new FileUploadResponse();
        fileService.uploadFile(file, null, COS_HOST,true,
                (res) -> {
                    BeanUtils.copyProperties(res, vo);
                },
                (e) -> {
                    handleFileUploadExceptionAsync(e);
                    log.error("上传文件失败", e);
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "上传头像失败");
                });
        return vo;
    }

    public String getFileUrl(Long fileId) {
        if (fileId == null) {
            return null;
        }
        FileStorageRecord record = fileService.getById(fileId);
        if (record == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "文件不存在");
        }
        return record.getFileUrl();
    }
}
